package com.globalwave.common.db.gen;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Id;
import javax.persistence.Table;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

import com.globalwave.common.db.SimpleJDBCDAO;


public class SQLGenerator {
    Log log = LogFactoryImpl.getLog(this.getClass()) ;
    
    protected SimpleJDBCDAO dao = null ;
    
    public SQLGenerator() {
        
    }
    
    public SQLGenerator(SimpleJDBCDAO dao) {
        this.dao = dao ;    
    }
    
    public static class WHERE {
        public StringBuffer sql = new StringBuffer();
        public List<Object> params = new ArrayList<Object>();
    }

    public static class INSERT {
        public StringBuffer sql = new StringBuffer();
        public List<Object> params = new ArrayList<Object>();
    }

    public static class UPDATE {
        public StringBuffer sql = new StringBuffer();
        public List<Object> params = new ArrayList<Object>();
    }

    public static class DELETE {
        public StringBuffer sql = new StringBuffer();
        public List<Object> params = new ArrayList<Object>();
    }

    public static class SELECT {
        public StringBuffer sql = new StringBuffer();
        public List<Object> params = new ArrayList<Object>();
    }
    
    public WHERE getWhere() throws Exception {
    	return null ;
    }/*
    public WHERE getWhere(Object object) throws Exception {
    	 if(object == null) {
             return new WHERE() ;
         }
    	 
    	 if (object instanceof Map) {
    		 return getMapGenerator(object).getWhere() ;
    	 } else {
    		 return getObjectGenerator(object).getWhere() ;
    	 }
    }*/

    public UPDATE getUpdate() throws Exception {
    	return null ;
    }
    /*
    public UPDATE getUpdate(Object obj) throws Exception {
    	if (obj instanceof Map) {
    		return this.getMapGenerator(obj).getUpdate();
    	} else {
    		return this.getObjectGenerator(obj).getUpdate();
    	}
    }*/

    public INSERT getInsert() throws Exception {
    	return null ;
    }
    /*
    public CREATE getCreate(Object obj) throws Exception {
    	if (obj instanceof Map) {
    		return this.getMapGenerator(obj).getCreate();
    	} else {
    		return this.getObjectGenerator(obj).getCreate();
    	}
    }*/

    public DELETE getDelete() throws Exception {
    	return getDelete(this.getTableName(), false) ;
    }

    public DELETE getDelete(String tableName) throws Exception {
    	return getDelete(tableName, false) ;
    }
    
    public DELETE getDelete(String tableName, boolean isById) throws Exception {

        WHERE where = isById?getIdWhere():null ;
        
        if (isById && where == null) {
        	throw new Exception("can't find id info!") ;
        }
        
        if (where == null) {
        	where = getWhere() ;
        }
        DELETE delete = new DELETE() ;
        delete.sql.append("DELETE FROM ").append(tableName).append(where.sql) ;
        delete.params = where.params ;
        
        return delete ;
    }


    public SELECT getSelect() throws Exception {
    	return getSelect(this.getTableName(), false) ;
    }
    
    public SELECT getSelect(boolean isById) throws Exception {
    	return getSelect(this.getTableName(), isById) ;
    }

    public SELECT getSelect(String tableName) throws Exception {
    	return getSelect(tableName, false) ;
    }

    public SELECT getSelect(String tableName, boolean isById) throws Exception {
    	return getSelect(tableName, null, isById) ;
    }
    
    public SELECT getSelect(String tableName, String[] colNames, boolean isById) throws Exception {
    	
    	StringBuffer selectSql = new StringBuffer() ;
    	
    	selectSql.append("SELECT ") ;
        
        if (colNames == null) {
        	selectSql.append("*") ;
        } else {
        	for (int i = 0 ; i < colNames.length ; i ++) {
        		if (i != 0) {
        			selectSql.append(" ,") ;
        		}
        		
        		selectSql.append(colNames[i]) ;
        	}
        }
        
        selectSql.append(" FROM ").append(tableName) ;
        
    	return getSelect(selectSql, isById) ;
    }
    
    public SELECT getSelect(StringBuffer selectSql, boolean isById) throws Exception {

        WHERE where = isById?getIdWhere():null ;
        
        if (isById && where == null) {
        	throw new Exception("can't find id info!") ;
        }
        
        if (where == null) {
        	where = getWhere() ;
        }
        SELECT select = new SELECT() ;
        
        select.sql.append(selectSql).append(where.sql) ;
        select.params = where.params ;
        
        return select ;
    }

    
    public WHERE getIdWhere() {
    	return null;
    }

    public Object getId(Id id, String tableName,String idName) throws Exception{
        long result = this.dao.getMaxId(tableName, idName) ;
        
        if (result == -1) {
            return null ;
        } else {
            return result ;
        }
    }
    
    public String getTableName() {
    	return null ;
    }
    
    public String getTableName(Class<?> clazz) {
        Table table = (Table) clazz.getAnnotation(Table.class) ;

        return table == null ? clazz.getSimpleName() : table.name() ;
    }
    
    public String toLower(String exp) {
        return String.format("LOWER(%s)", exp) ;
    }
    
}
